/**
*  \file md5.h
*
*  \brief Message-Digest Algorithm 5 (MD5)
*
*  This module calculates the MD5 checksum, a 128-bit hash value, of any message according to RFC1321.
*  To use this module it is necessary to provide a state object of the structure 'sMD5_state_t'.
*  The result (message digest) will be returned as four 32-bit words using the little endian convention.
*  The message digest starts with the least significant byte of the first hash word and ends with the most
*  significant byte of the last hash word.
*
*  \author D'Aprea F.  <francesco.daprea@linde-mh.de>
*
*  \include md5.example
*
*/

#ifndef MD5_H_INCLUDED
#define MD5_H_INCLUDED

/*================================================[ public includes  ]================================================*/

#include "../cfg/prj.h"

/*================================================[ public defines   ]================================================*/

#define MD5_NO_OF_HASH_PARTS          4U  /**< Number of 32-bit hash words.                              */
#define MD5_MSG_PACKET_SIZE          64U  /**< Message packet size in bytes.                             */
#define MD5_NO_OF_PACKET_WORDS       16U  /**< Number of 32-bit words each message packet.               */
#define MD5_MAX_SIZE_LAST_MSG_PACKET 55UL /**< Biggest possible data length in byte for user data inside
                                               the last message packet.                                  */

/* Magic hash init values according to RFC1321. */
#define MD5_HASH0_INIT 0x67452301UL /**< Magic start value for the 1st hash word according to RFC1321. */
#define MD5_HASH1_INIT 0xEFCDAB89UL /**< Magic start value for the 2nd hash word according to RFC1321. */
#define MD5_HASH2_INIT 0x98BADCFEUL /**< Magic start value for the 3rd hash word according to RFC1321. */
#define MD5_HASH3_INIT 0x10325476UL /**< Magic start value for the 4th hash word according to RFC1321. */

/*================================================[ public datatypes ]================================================*/

/**
*  The structure 'sMD5_state_t' defines all variables needed for the MD5 algorithm.
*  To use the MD5 algorithm it is necessary to provide an object of this datatype.
*  This object will represent the progress and state of the calculation.
*/
typedef struct
{
  U32 bData[MD5_NO_OF_PACKET_WORDS]; /**< Buffer with size of a 64-byte message packet to save and pad an incomplete packet
                                          from a passed message. */
  U32 bHash[MD5_NO_OF_HASH_PARTS];   /**< Buffer to return the calculated 128-bit message digest as four 32-bit words using
                                          the little endian convention. */
  U32 iDatasize[2U];                 /**< Size of passed message in byte: Field 0 contains low  order word,
                                                                          Field 1 contains high order word.
                                          Datasize will be automatically determined by calling the function md5_update() or
                                          md5_finalize(). */
} sMD5_state_t;

/*================================================[ public variables ]================================================*/

/*================================================[ public functions ]================================================*/

/**
*  Sets the MD5 state into the initial state by setting the MD5 hash constants and resetting the datasize counter.
*
*  \param  arg_ptr_state Pointer to the state object.
*          If NULL is passed, function will return RC_ERROR_NULL.
*
*  \return RC_SUCCESS if object is successfully initialized.
*/
RC md5_initialize( sMD5_state_t * const arg_ptr_state );

/**
*  This function allows to set user defined start constants for the hash words.
*
*  \param  arg_ptr_state  Pointer to the state object.
*			                 If NULL is passed, function will return RC_ERROR_NULL.
*  \param  arg_hash0_init User defined start constant for the 1st hash word.
*  \param  arg_hash1_init User defined start constant for the 2nd hash word.
*  \param  arg_hash2_init User defined start constant for the 3rd hash word.
*  \param  arg_hash3_init User defined start constant for the 4th hash word.
*
*  \return RC_SUCCESS if function finishes successfully.
*/
RC md5_set_start_hash( sMD5_state_t * const arg_ptr_state
                     , const U32 arg_hash0_init
                     , const U32 arg_hash1_init
                     , const U32 arg_hash2_init
                     , const U32 arg_hash3_init
                     );

/**
*
* Puts new data into internal packet buffer and calculates checksum if packet is complete.
*
*  \param arg_ptr_state Pointer to the state object.
*                       Includes current overall datalength, 64 bytes data buffer and 16 bytes hash buffer.
*					         If NULL is passed, function will return RC_ERROR_NULL.
*  \param arg_ptr_data  Pointer to new message data.
*  \param arg_datasize  Length of passed message data in bytes.
*
*  \return RC_SUCCESS if function finishes successfully.
*/
RC md5_update( sMD5_state_t * const arg_ptr_state, const U8 * arg_ptr_data, const U16 arg_datasize );

/**
*  Finalizes the calculation by padding the last message and returning the message digest.
*  Padding is done by appending the padding bytes and the datalength.
*  The padding bytes are defined in hash.h according to RFC1321.
*
*  \param arg_ptr_state       Pointer to the state object.
*						            If NULL is passed, function will return RC_ERROR_NULL.
*  \param arg_datasize_offset Offset to calculate the whole message length if alternative hash constants were used.
*                             In case of standard initialization this argument has to be zero.
*
*  \return RC_SUCCESS if function finishes successfully. Otherwise returns RC_ERROR.
*/
RC md5_finalize( sMD5_state_t * const arg_ptr_state
               , const U16 arg_datasize_offset
               );

/*====================================================================================================================*/

#endif

/***********************************************************************************************************************
*                             Copyright 2011 Linde Material Handling. All rights reserved.                             *
***********************************************************************************************************************/

